<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

use GatewayWorker\BusinessWorker;
use Workerman\Worker;
use GatewayWorker\Gateway;

//use GatewayClient\Gateway;
use GatewayWorker\Register;


class GatewayWorkerCommand extends Command
{
    private   $server;
    protected $actions = array('start', 'stop', 'reload', 'status', 'connections');

    /**
     * Workerman的测试，暂未使用
     *
     * 同时启用tcp与websocket
     * 1、设置不同的端口 9022、9033
     * 2、设置不同的起始监听端口:startPort 2300 与 2700
     */

    /***
     * 执行：监控
     * d:
     * cd D:\phpsite\laravel\work
     * php artisan gwk start
     *
     * 执行：新开窗口聊天
     *  telnet 127.0.0.1 12350
     *
     * 执行：新开窗口聊天
     *  telnet 127.0.0.1 12350
     *
     */
    // php artisan gwk action
    // php artisan gwk start
    // php artisan gwk restart
    // php artisan gwk stop
    protected $signature = 'gwk {action} {--itype=all : start} {--daemon} ';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'workerman 启动停止';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * [@return](https://learnku.com/users/31554) mixed
     */
    public function handle()
    {
        global $argv;

        //echo time();
        if(!in_array($action = $this->argument('action'), ['start', 'stop', 'restart'])){
            $this->error('输入action命令错误！！');
            exit;
        }

        $argv[0] = 'gateway-worker:server';
        $argv[1] = $action;
        $argv[2] = $this->option('daemon') ? '-d' : '';


        // 执行命令
        // 各种操作都是执行同一个命令
        /*switch ($action) {
            case 'start':
                $this->start();
                break;
            case 'stop':
                break;
            case 'restart':
                break;
            case 'reload':
                break;
            case 'status':
                break;
            case 'connections':
                break;
        }*/

        $this->start();
    }

    private function start()
    {
        global $argv;

        if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'){
            //针对 Windows 一次执行，无法注册多个协议的特殊处理
            $action = $this->argument('action');
            if($action === 'start'){
                $itype = $this->option('itype');
                if($itype === 'register'){
                    $this->startRegister();
                } elseif($itype === 'gateway'){
                    $this->startGateWay();
                } elseif($itype === 'worker'){
                    $this->startBusinessWorker();
                }
                Worker::runAll();

                return;
            }
        } else{

            $this->startRegister();
            $this->startTcpGateWay();
            $this->startGateWay();
            $this->startBusinessWorker();

            //Worker::runAll();
            \Workerman\Worker::runAll();
        }
    }

    private function startBusinessWorker()
    {
        $worker = new BusinessWorker();
        //$worker = new \GatewayWorker\BusinessWorker();

        $worker->name            = 'YourBusinessWorker';                        #设置BusinessWorker进程的名称
        $worker->count           = 4;                                       #设置BusinessWorker进程的数量
        $worker->registerAddress = '127.0.0.1:12350';                        #注册服务地址
        $worker->eventHandler    = \App\Events\Workerman::class;
        //$worker->eventHandler    = \App\GatewayWorker\Events::class;            #设置使用哪个类来处理业务,业务类至少要实现onMessage静态方法，onConnect和onClose静态方法可以不用实现
    }

    private function startGateWay()
    {
        $gateway = new Gateway("websocket://0.0.0.0:9022");  // 本地 9022 9033

        $gateway->name      = 'YourGateway';                         #设置Gateway进程的名称，方便status命令中查看统计
        $gateway->count     = 4;                                 #进程的数量
        $gateway->lanIp     = '127.0.0.1';                       #内网ip,多服务器分布式部署的时候需要填写真实的内网ip
        $gateway->startPort = 2700;                              #监听本机端口的起始端口
        //$gateway->pingInterval         = 30;
        //$gateway->pingNotResponseLimit = 0;                                 #服务端主动发送心跳
        //$gateway->pingData             = '{"mode":"heart"}';
        $gateway->registerAddress = '127.0.0.1:12350';                  #注册服务地址
        //Gateway::$registerAddress = '127.0.0.1:12350';


        $gateway->onMessage = function($connection, $data) {
            //echo "【".date('Y-m-d H:i:s')."】来自ip：".$connection->getRemoteIp().var_export($data, 1)."\n";
            $connection->send('hello world');
        };

        // 当客户端连接上来时，设置连接的onWebSocketConnect，即在websocket握手时的回调
        $gateway->onConnect = function($connection) {
            echo "【".date('Y-m-d H:i:s')."】有新的接入websocket，来自ip：".$connection->getRemoteIp()."\n";
            $connection->onWebSocketConnect = function($connection, $http_header) {
                // 可以在这里判断连接来源是否合法，不合法就关掉连接
                // $_SERVER['HTTP_ORIGIN']标识来自哪个站点的页面发起的websocket链接
                if(!empty($_SERVER['HTTP_ORIGIN'])){
                    if($_SERVER['HTTP_ORIGIN'] != 'http://chat.workerman.net'){
                        //$connection->close();
                    }
                }

                // onWebSocketConnect 里面$_GET $_SERVER是可用的
                //var_dump($_GET, $_SERVER);
            };
        };

        // 退出
        $gateway->onClose = function($connection) {
            echo "【".date('Y-m-d H:i:s')."】有退出websocket，来自ip：".$connection->getRemoteIp()."\n";
        };
    }

    // 在线 tcp 测试工具 https://xxf.cool/tools/tcpTool
    // 自己写的tcp工具，vendor扩展包报错
    private function startTcpGateWay()
    {
        $gateway = new Gateway("tcp://0.0.0.0:9033");  // 本地 9022 9033

        $gateway->name      = 'YourTcpGateway';                  #设置Gateway进程的名称，方便status命令中查看统计
        $gateway->count     = 4;                                 #进程的数量
        $gateway->lanIp     = '127.0.0.1';                       #内网ip,多服务器分布式部署的时候需要填写真实的内网ip
        $gateway->startPort = 2400;                              #监听本机端口的起始端口
        //$gateway->pingInterval         = 30;
        //$gateway->pingNotResponseLimit = 0;                                 #服务端主动发送心跳
        //$gateway->pingData             = '{"mode":"heart"}';
        $gateway->registerAddress = '127.0.0.1:12350';                  #注册服务地址
        //Gateway::$registerAddress = '127.0.0.1:12360';


        $gateway->onMessage = function($connection, $data) {
            $connection->send('hello world');
        };

        // 当客户端连接上来时，设置连接的onWebSocketConnect，即在websocket握手时的回调
        $gateway->onConnect = function($connection) {
            echo "【".date('Y-m-d H:i:s')."】有新的接入tcp，来自ip：".$connection->getRemoteIp()."\n";
            $connection->onWebSocketConnect = function($connection, $http_header) {
                // 可以在这里判断连接来源是否合法，不合法就关掉连接
                // $_SERVER['HTTP_ORIGIN']标识来自哪个站点的页面发起的websocket链接
                if(!empty($_SERVER['HTTP_ORIGIN'])){
                    if($_SERVER['HTTP_ORIGIN'] != 'http://chat.workerman.net'){
                        //$connection->close();
                    }
                }

                // onWebSocketConnect 里面$_GET $_SERVER是可用的
                //var_dump($_GET, $_SERVER);
            };
        };

        // 退出
        $gateway->onClose = function($connection) {
            echo "【".date('Y-m-d H:i:s')."】有退出tcp，来自ip：".$connection->getRemoteIp()."\n";
        };
    }

    private function startRegister()
    {
        new Register('text://0.0.0.0:12350');
        //new \GatewayWorker\Register('text://0.0.0.0:12350');
    }


}
